package com.syx.friend.Service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.syx.commoncore.Constant.Constant;
import com.syx.commoncore.Constant.Constants;
import com.syx.commoncore.Constant.HttpConstants;
import com.syx.commoncore.Model.LoginUser;
import com.syx.commoncore.Model.Result;
import com.syx.commoncore.Utils.EmailSendUtils;
import com.syx.commoncore.Utils.ThreadLocalUtil;
import com.syx.commoncore.enums.Resultcode;
import com.syx.commoncore.enums.UserIdEnum;
import com.syx.friend.Manager.UserCacheManager;
import com.syx.friend.Mapper.UserMapper;
import com.syx.friend.Model.user.DTO.UserUpdateDTO;
import com.syx.friend.Model.user.User;
import com.syx.friend.Model.user.DTO.UserDTO;
import com.syx.friend.Model.user.VO.UserVO;
import com.syx.friend.Service.IUserService;
import com.syx.security.Exception.ServiceException;
import com.syx.security.Service.TokenService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class IUserServiceImpl implements IUserService {
    @Resource
    TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;

    @Resource
    UserMapper userMapper;

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    EmailSendUtils emailSendUtils;

    @Resource
    UserCacheManager userCacheManager;

    @Value("${file.oss.downloadUrl}")
    private String downloadUrl;



    @Override
    public Result<Void> sendCode(UserDTO userDTO) {

        emailSendUtils.sendVerificationEmail(userDTO.getEmail());


        return Result.success();

    }

    //登录时候验证验证码是否正确，返回token
    @Override
    public Result emailLogin(UserDTO userDTO) {
        //登录兼注册
        //如果未登录
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getEmail, userDTO.getEmail()));
        if (user==null){
            //未注册
            User newUser=new User();
            BeanUtil.copyProperties(userDTO,newUser);
            int insertRow = userMapper.insert(newUser);
            if (insertRow!=1){
                throw new ServiceException(Resultcode.REGISTER_FAILURE);

            }
        }
        //走到这要么注册成功要么已经有内容了
        User user1 = userMapper.selectOne(new LambdaQueryWrapper<User>().select(User::getUserId,User::getStatus).eq(User::getEmail, userDTO.getEmail()));
        String email_code = (String) redisTemplate.opsForValue().get(Constants.EMAIL_CODE.getValue()+userDTO.getEmail());
        if(!userDTO.getCode().equals(email_code)){
            throw new ServiceException(Resultcode.EMAIL_CODE_ERROR);
        }
        redisTemplate.delete(Constants.EMAIL_CODE.getValue());
        String token = tokenService.createEmailToken(user1.getUserId(),secret, UserIdEnum.ORDINARY.getValue(),user1.getStatus());

        return Result.success(token);


    }

    @Override
    public Result<Void> logout(String token) {
        if (StrUtil.isNotEmpty(token) &&
                token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        tokenService.deleteToken(token,secret);
        return Result.success();


    }

    //检查用户登录状态
    @Override
    public Result<UserVO> info(String token) {
        //解析token,获取用户的信息
        if (StrUtil.isNotEmpty(token) &&
                token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        LoginUser loginUser = tokenService.getLoginUser(token, secret);

        if (loginUser==null){
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS.toString());
        }
        UserVO userVO=new UserVO();
        userVO.setNickName(loginUser.getNickName());



        return Result.success(userVO);



    }

    @Override
    public Result<UserVO> detail() {
        Long userId = ThreadLocalUtil.get(Constant.USER_ID, Long.class);
        if (userId==null){
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS);
        }
        //userId不为空的情况下
        UserVO userVO = userCacheManager.getUserById(userId);


        if (userVO==null){
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS);
        }
        return Result.success(userVO);


    }

    @Override
    public Result edit(UserUpdateDTO userUpdateDTO) {
        Long userId = ThreadLocalUtil.get(Constant.USER_ID, Long.class);
        if (userId == null) {
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS);
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS);
        }
        user.setNickName(userUpdateDTO.getNickName());
        user.setSex(userUpdateDTO.getSex());
        user.setSchoolName(userUpdateDTO.getSchoolName());
        user.setMajorName(userUpdateDTO.getMajorName());
        user.setPhone(userUpdateDTO.getPhone());
        user.setEmail(userUpdateDTO.getEmail());
        user.setWechat(userUpdateDTO.getWechat());
        user.setIntroduce(userUpdateDTO.getIntroduce());
        //更新用户缓存
        userCacheManager.refreshUser(user);


        int i = userMapper.updateById(user);
        if (i!=1){
            throw new ServiceException(Resultcode.FAILED_INSERT);
        }
        return Result.success();
    }

    @Override
    public Result<Void> updateHeadImage(String headImage) {
        Long userId = ThreadLocalUtil.get(Constant.USER_ID, Long.class);
        if (userId == null) {
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS);
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new ServiceException(Resultcode.FAILED_USER_NOT_EXISTS);
        }
        user.setHeadImage(headImage);
        //更新用户缓存
        userCacheManager.refreshUser(user);


        int i = userMapper.updateById(user);
        if (i!=1){
            throw new ServiceException(Resultcode.FAILED_INSERT);
        }
        return Result.success();
    }

}
